package com.zzw.annotation.runners;

import com.zzw.annotation.RequestResource;
import com.zzw.annotation.vo.DefaultRequestResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Administrator
 */
public class RequestResourceRunner implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(RequestResourceRunner.class);

    private static final ConcurrentHashMap<String, DefaultRequestResource> REQUEST_RESOURCE_CONCURRENT_HASH_MAP = new ConcurrentHashMap<>();

    private final ApplicationContext applicationContext;

    public RequestResourceRunner(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public DefaultRequestResource getRequestResource(String path) {
        return REQUEST_RESOURCE_CONCURRENT_HASH_MAP.get(path);
    }

    @Override
    public void run(String... args) throws Exception {
        applicationContext.getBeansWithAnnotation(Controller.class).forEach((beanName, bean) -> {
            Class<?> beanClass = bean.getClass();
            for (Method method : beanClass.getDeclaredMethods()) {
                if (method.isAnnotationPresent(RequestResource.class)) {
                    Annotation[] declaredAnnotations = method.getAnnotations();
                    RequestResource requestResource = method.getAnnotation(RequestResource.class);
                    for (Annotation declaredAnnotation : declaredAnnotations) {
                        if (declaredAnnotation instanceof PostMapping || declaredAnnotation instanceof GetMapping || declaredAnnotation instanceof RequestMapping
                                || declaredAnnotation instanceof PutMapping || declaredAnnotation instanceof DeleteMapping) {
                            String[] values = (String[]) AnnotationUtils.getValue(declaredAnnotation);
                            if (values != null) {
                                for (String value : values) {
                                    DefaultRequestResource defaultRequestResource = new DefaultRequestResource();
                                    defaultRequestResource.setPath(value);
                                    defaultRequestResource.setQps(requestResource.qps());
                                    defaultRequestResource.setLimitKey(requestResource.limitKey());
                                    REQUEST_RESOURCE_CONCURRENT_HASH_MAP.put(value, defaultRequestResource);
                                }
                            }
                        }
                    }
                }
            }
        });
    }
}
